package com.googlecode.horncomb.util.lang;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * Provides a helper that locates the declarated generics type of a class.
 * 泛型类类型获取。
 * @author Daniel
 */
public abstract class GenericsUtil {

	/**
	 * Locates the first generic declaration on a class.
	 * @param clazz
	 *            The class to introspect
	 * @return the first generic declaration, or <code>null</code> if cannot be
	 *         determined
	 */
	public static Class<? extends Object> getGenericClass(
			Class<? extends Object> clazz) {
		return getGenericClassFromSuper(clazz, 0);
	}

	/**
	 * Locates generic declaration by index on a class.
	 * @param clazz
	 *            clazz The class to introspect
	 * @param index
	 *            the Index of the generic ddeclaration,start from 0.
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Class<? extends Object> getGenericClassFromSuper(
			Class<? extends Object> clazz, final int index) {
		Type genericType = clazz.getGenericSuperclass();
		try {
			if (genericType instanceof ParameterizedType) {
				Type[] params = ((ParameterizedType) genericType)
						.getActualTypeArguments();

				if ((params != null) && (params.length >= (index - 1))) {
					return (Class<? extends Object>) params[index];
				}
			}
		} catch (ClassCastException ex) {
			// do nothing
		}
		return null;
	}
}
